home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / raid / debugMem.c < prev    next >
C/C++ Source or Header  |  1990-10-12  |  5KB  |  196 lines

  1. /* 
  2.  * devDebugMem.c --
  3.  *
  4.  *    Initially, this module was created to detect bugs associated with
  5.  *    memory allocation/deallocation (i.e. memory leakage, freeing of
  6.  *    unallocated memory locations etc...).
  7.  *    Since then, it has been expanded to deal with the problem that
  8.  *    'free' can not be called from an interrupt routine.
  9.  *    The 'Free' procedure defined in this module, places the mem block to
  10.  *    be freed on a to-be-freed list rather than calling 'free' directly.
  11.  *    All mem blocks on the to-be-freed list are freed the next time
  12.  *    'Malloc' is called.
  13.  *
  14.  * Copyright 1989 Regents of the University of California
  15.  * Permission to use, copy, modify, and distribute this
  16.  * software and its documentation for any purpose and without
  17.  * fee is hereby granted, provided that the above copyright
  18.  * notice appear in all copies.  The University of California
  19.  * makes no representations about the suitability of this
  20.  * software for any purpose.  It is provided "as is" without
  21.  * express or implied warranty.
  22.  *
  23.  */
  24.  
  25. #ifndef lint
  26. static char rcsid[] = "$Header: /sprite/src/kernel/raid/RCS/debugMem.c,v 1.6 90/10/12 14:00:48 eklee Exp $ SPRITE (Berkeley)";
  27. #endif /* not lint */
  28.  
  29. #include "sync.h"
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include "hash.h"
  33.  
  34. extern char *malloc();
  35.  
  36. #define FREE_LIST_SIZE    4096
  37. #define LOCK_TABLE_SIZE    4096
  38.  
  39. #ifdef TESTING
  40. static Hash_Table _debugMemTable;
  41. static _debugMemCount = 0;
  42. #endif TESTING
  43. static Sync_Semaphore _debugMemMutex =
  44.     Sync_SemInitStatic("devRaidLock.c: DebugMem Lock Table");
  45. static char *freeList[FREE_LIST_SIZE];
  46. static int freeListIndex = 0;
  47.  
  48.  
  49. /*
  50.  *----------------------------------------------------------------------
  51.  *
  52.  * InitDebugMem --
  53.  *
  54.  *    This procedure should be the first procedure to be called from this
  55.  *    module.
  56.  *
  57.  * Results:
  58.  *    None.
  59.  *
  60.  * Side effects:
  61.  *    Initializes data structures.
  62.  *
  63.  *----------------------------------------------------------------------
  64.  */
  65.  
  66. void
  67. InitDebugMem()
  68. {
  69. #ifdef TESTING
  70.     static int    initialized = 0;
  71.  
  72.     MASTER_LOCK(&_debugMemMutex);
  73.     if (initialized == 0) {
  74.     initialized = 1;
  75.         MASTER_UNLOCK(&_debugMemMutex);
  76.         Hash_Init(&_debugMemTable, 1000, 1);
  77.     } else {
  78.     MASTER_UNLOCK(&_debugMemMutex);
  79.     }
  80. #endif TESTING
  81. }
  82.  
  83.  
  84. /*
  85.  *----------------------------------------------------------------------
  86.  *
  87.  * Free --
  88.  *
  89.  *    Replacement procedure for 'free' which can be called from interrupt
  90.  *    routines.
  91.  *
  92.  * Results:
  93.  *    None.
  94.  *
  95.  * Side effects:
  96.  *    Places mem block to be freed on a global to-be-freed list.
  97.  *
  98.  *----------------------------------------------------------------------
  99.  */
  100.  
  101. void
  102. Free(memPtr)
  103.     char *memPtr;
  104. {
  105.     MASTER_LOCK(&_debugMemMutex);
  106.     if (freeListIndex == FREE_LIST_SIZE) {
  107.         MASTER_UNLOCK(&_debugMemMutex);
  108.     printf("Error: Free: free list overflow\n");
  109.     } else {
  110.         freeList[freeListIndex] = memPtr;
  111.     freeListIndex++;
  112.         MASTER_UNLOCK(&_debugMemMutex);
  113.     }
  114. #ifdef TESTING
  115. {
  116.     Hash_Entry        *hashEntryPtr;
  117.  
  118.     MASTER_LOCK(&_debugMemMutex);
  119.     if (--_debugMemCount == 0) {
  120.         MASTER_UNLOCK(&_debugMemMutex);
  121.     printf("Msg: Free: _debugMemCount == 0\n");
  122.     } else {
  123.         MASTER_UNLOCK(&_debugMemMutex);
  124.     }
  125.     MASTER_LOCK(&_debugMemMutex);
  126.     hashEntryPtr = Hash_Find(&_debugMemTable, (Address) memPtr);
  127.     if ( Hash_GetValue(hashEntryPtr) == (char *) NIL ) {
  128.         MASTER_UNLOCK(&_debugMemMutex);
  129.     printf("Error: Free: unallocated mem=%x freed\n", memPtr);
  130.     } else {
  131.         Hash_Delete(&_debugMemTable, hashEntryPtr);
  132.         MASTER_UNLOCK(&_debugMemMutex);
  133.     }
  134. }
  135. #endif TESTING
  136. }
  137.  
  138.  
  139. /*
  140.  *----------------------------------------------------------------------
  141.  *
  142.  * Malloc --
  143.  *
  144.  *    Replacement procedure for 'malloc'.
  145.  *    Should be used with 'Free'.
  146.  *
  147.  * Results:
  148.  *    Newly allocated memory block.
  149.  *
  150.  * Side effects:
  151.  *    Frees mem blocks on global to-be-freed list
  152.  *    Calls 'malloc' to allocate memory.
  153.  *
  154.  *----------------------------------------------------------------------
  155.  */
  156.  
  157. char *
  158. Malloc(size)
  159.     unsigned size;
  160. {
  161.     char *memPtr;
  162.  
  163.     MASTER_LOCK(&_debugMemMutex);
  164.     for (; freeListIndex > 0;) {
  165.     freeListIndex--;
  166.     free(freeList[freeListIndex]);
  167.     }
  168.     MASTER_UNLOCK(&_debugMemMutex);
  169.  
  170.     memPtr = malloc(size);
  171.  
  172. #ifdef TESTING
  173. {
  174.     Hash_Entry        *hashEntryPtr;
  175.  
  176.     MASTER_LOCK(&_debugMemMutex);
  177.     if (_debugMemCount++ == 0) {
  178.         MASTER_UNLOCK(&_debugMemMutex);
  179.     printf("Msg: Malloc: _debugMemCount == 0\n");
  180.     } else {
  181.         MASTER_UNLOCK(&_debugMemMutex);
  182.     }
  183.     MASTER_LOCK(&_debugMemMutex);
  184.     hashEntryPtr = Hash_Find(&_debugMemTable, memPtr);
  185.     if ( Hash_GetValue(hashEntryPtr) != (char *) NIL ) {
  186.         MASTER_UNLOCK(&_debugMemMutex);
  187.     printf("Error: Malloc: allocated mem=%x reallocated\n", memPtr);
  188.     } else {
  189.         MASTER_UNLOCK(&_debugMemMutex);
  190.     }
  191.     Hash_SetValue(hashEntryPtr, memPtr);
  192. }
  193. #endif TESTING
  194.     return(memPtr);
  195. }
  196.